#!/bin/bash
# vim: fdm=marker fmr=[[[,]]] cms=\ #%s#

build_apache()
{ #[[[#
    local web_dir=$1
    local server_dir=${web_dir}/apache
    local pkg_dir=$2

    if [[ -e $server_dir ]]
    then
        if [[ ! -d $server_dir || ! -w $server_dir ]]
        then
            echo "Error: $server_dir not directory or writeable"
            return 1
        fi
        rm -fr $server_dir/*
    else
        mkdir $server_dir
        if (( $? != 0 ))
        then
            echo "Error: create $server_dir fail"
            return 1
        fi
    fi

#    local limit_tar=$pkg_dir/$(grep mod_limitipconn $pkg_dir/list)
#    local cronolog_tar=$pkg_dir/$(grep cronolog $pkg_dir/list)
    local httpd_tar=$pkg_dir/$(grep httpd $pkg_dir/list)
    local php_tar=$pkg_dir/$(grep php $pkg_dir/list)
#    if [[ ! -f "$limit_tar" || ! -f "$cronolog_tar" || \
#    ! -f "$httpd_tar" || ! -f "$php_tar" ]]
    if [[ ! -f "$httpd_tar" || ! -f "$php_tar" ]]
    then
        echo "Error: pkg in $pkg_dir not found" 
        return 1
    fi

    mkdir -p _pkg
    cd _pkg             # /_pkg
    rm -fr *

    #=== Check pkg ===#
    # Check httpd
    local httpd_dir
    httpd_dir=$(basename $httpd_tar)
    httpd_dir=${httpd_dir%.tar.gz}
    tar -zxf $httpd_tar
    echo "APACHE: $httpd_dir"

    # Check mod_limitipconn
#    local limit_dir
#    limit_dir=$(basename $limit_tar)
#    limit_dir=${limit_dir%.tar.gz}
#    tar -zxf $limit_tar
#    echo "MOD_LIMITIPCONN: $limit_dir"

    # Check cronolog
#    local cronolog_dir
#    cronolog_dir=$(basename $cronolog_tar)
#    cronolog_dir=${cronolog_dir%.tar.gz}
#    tar -zxf $cronolog_tar
#    echo "CRONOLOG: $cronolog_dir"

    # Check php
    local php_dir
    php_dir=$(basename $php_tar)
    php_dir=${php_dir%.tar.gz}
    tar -zxf $php_tar
    echo "PHP: $php_dir"

    #=== Compile apache ===#
    cd $httpd_dir      # /_pkg/httpd_dir
    ./configure --silent --prefix=$server_dir --enable-so --enable-mods-shared=most --with-mpm=worker --enable-ssl --enable-rewrite
# --with-expat=builtin
    if (( $? != 0))
    then
        echo "Error: apache configure fail"
        return 1
    fi
    make -s
    if (( $? != 0))
    then
        echo "Error: apache make fail"
        return 1
    fi
    make -s install
    if (( $? != 0))
    then
        echo "Error: apache install fail"
        return 1
    fi

    # 加入limitipconn
#    cd ../$limit_dir    # /_pkg/limit_dir
#    PATH=$PATH:$server_dir/bin
#    make -s
#    make -s install

    # 加入cronolog
#    cd ../$cronolog_dir    # /_pkg/cronolog_dir
#    ./configure --silent
#    make -s
#    cp src/cronolog $server_dir/bin

    # 修改 httpd.conf
    awk '
/^ *ServerAdmin/ {
    printf("ServerAdmin webmaster@site.com\n");
    next;
}
/^ *# *ServerName/ {
    printf("ServerName site.com\n");
    next;
}
/^ *DocumentRoot/ {
    printf("DocumentRoot \"%s/htdocs\"\n", web_dir);
    next;
}
/^ *<Directory.*htdocs.*>/ {
    printf("<Directory \"%s/htdocs\">\n", web_dir);
    next;
}
/ *DirectoryIndex index\.html/ {
    printf("DirectoryIndex index.html index.htm index.php\n");
    next;
}
/ *AddType application\/x-gzip/ {
    print;
    printf("    AddType application/x-httpd-php .php .inc .api\n");
    next;
}
#/^ *ErrorLog/ {
#    printf("ErrorLog \"|%s/bin/cronolog %s/logs/errorlog/%%Y-%%m-%%d-error.log\"\n", server_dir, server_dir);
#    next;
#}
#/^ *CustomLog/ {
#    printf("CustomLog \"|%s/bin/cronolog %s/logs/customlog/%%Y-%%m-%%d-access.log\" combined\n", server_dir, server_dir);
#    next;
#}
/^ *#Include conf\/extra\/httpd-mpm\.conf/ {
    printf("Include conf/extra/httpd-mpm.conf\n");
    next;
}
/^ *#Include conf\/extra\/httpd-default\.conf/ {
    printf("Include conf/extra/httpd-default.conf\n");
    next;
}
#/^ *#Include conf\/extra\/httpd-ssl\.conf/ {
#    printf("Include conf/extra/httpd-ssl.conf\n");
#    next;
#}
{
    gsub("Indexes", "");
    print;
}
' web_dir=$web_dir server_dir=$server_dir $server_dir/conf/httpd.conf >httpd.conf.tmp
    echo "
AddDefaultCharset UTF-8

#<IfModule mod_limitipconn>
#<Location />
#    MaxConnPerIP 5
#</Location>
#</IfModule>
" >>httpd.conf.tmp
    mv -f httpd.conf.tmp $server_dir/conf/httpd.conf

    # extra/httpd-default.conf
    awk '
/^ *Timeout / {
    printf("Timeout 60\n");
    next;
}
#/^ *KeepAlive / {
#    printf("KeepAlive Off\n");
#    next;
#}
{ print; }
' $server_dir/conf/extra/httpd-default.conf >httpd-default.conf.tmp
    mv -f httpd-default.conf.tmp $server_dir/conf/extra/httpd-default.conf

    # extra/httpd-autoindex.conf
#    awk '
#{
#    gsub("Indexes", "");
#    print;
#}
#' $server_dir/conf/extra/httpd-autoindex.conf >httpd-autoindex.conf.tmp
#    mv -f httpd-autoindex.conf.tmp $server_dir/conf/extra/httpd-autoindex.conf

    # extra/httpd-ssl.conf
    awk '
/^ *ServerName/ {
    printf("ServerName site.com\n");
    next;
}
/^ *ServerAdmin/ {
    printf("ServerAdmin webmaster@site.com\n");
    next;
}
/^ *DocumentRoot/ {
    printf("DocumentRoot \"%s/htdocs\"\n", web_dir);
    next;
}
/^ *SSLCertificateFile/ {
    printf("SSLCertificateFile %s/conf/ssl.crt/site.crt\n", server_dir);
    next;
}
/^ *SSLCertificateKeyFile/ {
    printf("SSLCertificateKeyFile %s/conf/ssl.key/site.key\n", server_dir);
    next;
}
{ print; }
' web_dir=$web_dir server_dir=$server_dir $server_dir/conf/extra/httpd-ssl.conf > httpd-ssl.conf.tmp
    mv -f httpd-ssl.conf.tmp $server_dir/conf/extra/httpd-ssl.conf

    #=== 编译PHP ===#
    cd ../$php_dir  # /_pkg/php_dir

    ./buildconf --force
    local libdir
    case $CPU in
    i386|i686) libdir=lib ;;
    x86_64) libdir=lib64 ;;
    esac
    ./configure --silent --with-libdir=$libdir --prefix=$server_dir/php --with-config-file-path=$server_dir/conf --disable-debug --with-apxs2=$server_dir/bin/apxs --enable-cli --enable-sockets --enable-sysvmsg --enable-soap --enable-mbstring --with-zlib --with-openssl --with-iconv --with-mysql --without-sqlite --enable-gd-native-ttf --with-gd --with-png-dir --with-jpeg-dir --with-ttf --with-freetype-dir
    if (( $? != 0 ))
    then
        echo "Error: PHP configure fail"
        return 1
    fi
    make -s clean
    make -s
    if (( $? != 0 ))
    then
        echo "Error: PHP make fail"
        return 1       
    fi
    make -s install
    if (( $? != 0 ))
    then
        echo "Error: PHP install fail"
        return 1       
    fi

    # 改写php.ini
    awk '
/^ display_errors *=/ {
	printf("display_errors = Off\n");
	next;
}
/log_errors *=/ {
	printf("log_errors = On\n");
	next;
}
/error_log *= *filename/ {
    printf("error_log = %s/logs/php.error.log\n", server_dir);
    next;
}
{ print; }
' server_dir=$server_dir php.ini-dist > $server_dir/conf/php.ini

    cd ..                   # /_pkg

    cd ..                   # /

    #=== Configure ===#
    cd apache               # /apache

    # Append to php.ini
    cat php.ini >>$server_dir/conf/php.ini
    # svrctl
    cp svrctl_tmpl.sh $server_dir/bin/svrctl
    chmod 755 $server_dir/bin/svrctl
    # site crt & key
    mkdir -p $server_dir/conf/ssl.crt
    cp site.crt $server_dir/conf/ssl.crt
    mkdir -p $server_dir/conf/ssl.key
    cp site.key $server_dir/conf/ssl.key

    chmod 777 $server_dir/logs
    mkdir $server_dir/logs/errorlog $server_dir/logs/customlog
    chmod 777 $server_dir/logs/*

    cd ..                   # /
} #]]]#

build_nginx()
{ #[[[#
    local web_dir=$1
    local server_dir=${web_dir}/nginx
    local pkg_dir=$2

    if [[ -e $server_dir ]]
    then
        if [[ ! -d $server_dir || ! -w $server_dir ]]
        then
            echo "Error: $server_dir not directory or writeable"
            return 1
        fi
        rm -fr $server_dir/*
    else
        mkdir $server_dir
        if (( $? != 0 ))
        then
            echo "Error: create $server_dir fail"
            return 1
        fi
    fi

    local nginx_tar=$pkg_dir/$(grep nginx $pkg_dir/list)
    local php_tar=$pkg_dir/$(grep php $pkg_dir/list)
    if [[ ! -f "$nginx_tar" || ! -f "$php_tar" ]]
    then
        echo "Error: pkg in $pkg_dir not found" 
        return 1
    fi

    mkdir -p _pkg
    cd _pkg             # /_pkg
    rm -fr *

    #=== Check pkg ===#
    # Check nginx
    local nginx_dir
    nginx_dir=$(basename $nginx_tar)
    nginx_dir=${nginx_dir%.tar.gz}
    tar -zxf $nginx_tar
    echo "nginx: $nginx_dir"

    # Check php
    local php_dir
    php_dir=$(basename $php_tar)
    php_dir=${php_dir%.tar.gz}
    tar -zxf $php_tar
    echo "php: $php_dir"

    #=== Compile nginx ===#
    cd $nginx_dir           # /_pkg/nginx_dir

    ./configure --prefix=$server_dir --with-http_stub_status_module --with-http_ssl_module
    if (( $? != 0))
    then
        echo "Error: nginx configure fail"
        return 1
    fi
    make -s
    if (( $? != 0))
    then
        echo "Error: nginx make fail"
        return 1
    fi
    make -s install
    if (( $? != 0))
    then
        echo "Error: nginx install fail"
        return 1
    fi

    cd ..                   # /_pkg

    #=== Compile PHP ===#
    cd $php_dir             # /_pkg/php_dir

    ./buildconf --force
    local libdir
    case $CPU in
    i386|i686) libdir=lib ;;
    x86_64) libdir=lib64 ;;
    esac
    ./configure --silent --with-libdir=$libdir --prefix=$server_dir/php --with-config-file-path=$server_dir/conf --disable-debug --enable-fastcgi --enable-cli --enable-sockets --enable-soap --enable-mbstring --with-zlib --with-openssl --with-iconv --with-mysql --without-sqlite --enable-gd-native-ttf --with-gd --with-png-dir --with-jpeg-dir --with-ttf --with-freetype-dir
    if (( $? != 0 ))
    then
        echo "Error: PHP configure fail"
        return 1
    fi
    make -s clean
    make -s
    if (( $? != 0 ))
    then
        echo "Error: PHP make fail"
        return 1       
    fi
    make -s install
    if (( $? != 0 ))
    then
        echo "Error: PHP install fail"
        return 1       
    fi

    # 改写php.ini
    awk '
/^ display_errors *=/ {
	printf("display_errors = Off\n");
	next;
}
/log_errors *=/ {
	printf("log_errors = On\n");
	next;
}
/error_log *= *filename/ {
    printf("error_log = %s/logs/php.error.log\n", server_dir);
    next;
}
{ print; }
' server_dir=$server_dir php.ini-dist > $server_dir/conf/php.ini

    cd ..                   # /_pkg

    cd ..                   # /

    #=== Configure ===#
    cd nginx                # /nginx

    # nginx.conf
    cp -f nginx.conf $server_dir/conf
    # Append to php.ini
    cat php.ini >>$server_dir/conf/php.ini
    # svrctl
    mkdir $server_dir/bin
    cp svrctl_tmpl.sh $server_dir/bin/svrctl
    chmod 755 $server_dir/bin/svrctl
#    # site crt & key
#    mkdir -p $server_dir/conf/ssl.crt
#    cp site.crt $server_dir/conf/ssl.crt
#    mkdir -p $server_dir/conf/ssl.key
#    cp site.key $server_dir/conf/ssl.key

    chmod 777 $server_dir/logs
#    mkdir $server_dir/logs/errorlog $server_dir/logs/customlog
#    chmod 777 $server_dir/logs/*

    cd ..                   # /
} #]]]#

copy_program()
{ #[[[#
    local web_dir=$1

    cd phpinc               # /phpinc
    mkdir -p $web_dir/phpinc/soar
    cp -f soar/*.inc $web_dir/phpinc/soar
    cd ..                   # /

    cd htdocs/test          # /htdocs/test
    mkdir -p $web_dir/htdocs/test
    cp -f *.php $web_dir/htdocs/test
    cd ../..                # /
} #]]]#

main()
{ #[[[#
    if [[ ! -f "${PWD}/$(basename $0)" ]]
    then
        echo
        echo "Error: must execute under pwd of $(basename $0)"
        echo
        return 1
    fi

    local web_dir=/opt/soar/web
    local pkg_dir=${PWD}/../build/pkg

    if [[ -e $web_dir ]]
    then
        if [[ ! -d $web_dir || ! -w $web_dir ]]
        then
            echo "Error: $web_dir not directory or writeable"
            return 1
        fi
    else
        mkdir $web_dir
        if (( $? != 0 ))
        then
            echo "Error: create $web_dir fail"
            return 1
        fi
    fi

# apache + php shared module
    build_apache "$web_dir" "$pkg_dir"
    if (( $? != 0 ))
    then
        echo
        echo "Error: compile apache fail"
        echo
        return 1
    fi

# nginx + php fast-cgi
    build_nginx "$web_dir" "$pkg_dir"
    if (( $? != 0 ))
    then
        echo
        echo "Error: compile nginx fail"
        echo
        return 1
    fi

# program
    copy_program "$web_dir"

    echo
    echo "Succeed"
    echo
} #]]]#

CPU=$(uname -m | tr '[:upper:]' '[:lower:]')

main
exit $?
